package com.unnet.yjs.exception;


import com.alibaba.fastjson.JSONObject;
import com.unnet.yjs.util.RestResponse;
import com.unnet.yjs.util.ToolUtil;
import com.xiaoleilu.hutool.log.Log;
import com.xiaoleilu.hutool.log.LogFactory;
import org.apache.catalina.connector.ClientAbortException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 *  Email: love1208tt@foxmail.com
 *  Copyright (c) 2018. missbe
 *  @author lyg  19-5-21 下午9:43
 *
 **/

@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Log log = LogFactory.get();

    /**
     * 500 - Bad Request
     */
    @ExceptionHandler({HttpMessageNotReadableException.class,
            HttpRequestMethodNotSupportedException.class,
            HttpMediaTypeNotSupportedException.class,
            SQLException.class,Exception.class})
    @ResponseBody
    public RestResponse handleHttpMessageNotReadableException(HttpServletRequest request,
                                                              HttpServletResponse response,
                                                              Exception e){
        Map<String,Object> map = new HashMap<>();
        map.put("url", request.getRequestURI());
        map.put("res", response.getStatus());
        map.put("msg", e.getMessage());
        return RestResponse.failure("500 Internal Error.").setData(map);
    }

    @ExceptionHandler(ClientAbortException.class)
    @ResponseBody
    protected ResponseEntity<String> handleExceptions(Exception ex) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.set("Content-Type", "application/json;charset=UTF-8");
        if ("org.apache.catalina.connector.ClientAbortException".equals(ex.getClass().getName())) {
            log.error("ClientAbortException,message:{}",ex.getLocalizedMessage());
            return new ResponseEntity<String>("{\"code\":500,\"data\":null,\"msg\":\"" + ex.getLocalizedMessage() + "\"}", httpHeaders, HttpStatus.OK);
        }

        return new ResponseEntity<String>(
                "{\"code\":500,\"data\":null,\"msg\":\"服务器闹脾气，请稍后再试\"}", httpHeaders, HttpStatus.OK);
    }

    @ExceptionHandler(MyException.class)
    @ResponseBody
    public RestResponse resolveException(HttpServletRequest request,
                                         HttpServletResponse response,
                                         MyException exception) {
        if (ToolUtil.isAjax(request)) {
            try {
                response.setContentType("application/json;charset=UTF-8");
                PrintWriter writer = response.getWriter();
                RestResponse failResponse = RestResponse.failure("您无此权限,请联系管理员!");
                writer.write(JSONObject.toJSONString(failResponse));
                writer.flush();
                writer.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }else {
            Map<String,Object> map = new HashMap<>();
            map.put("url", request.getRequestURI());
            map.put("msg",exception.getMessage());
            return RestResponse.failure("500错误").setData(map);
        }

        return null;
    }

    /**
     * 404的拦截.
     */
    @ResponseStatus(code = HttpStatus.NOT_FOUND)
    @ExceptionHandler(NoHandlerFoundException.class)
    @ResponseBody
    public RestResponse notFound(HttpServletRequest request, HttpServletResponse response, Exception ex) {
        Map<String,Object> map = new HashMap<>();
        map.put("errMsg", ex.getLocalizedMessage());
        map.put("url",request.getRequestURI());
        map.put("res", response.getStatus());

        return RestResponse.failure("404 Not Found.").setData(map).setCode(404);
    }

    @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(MyException.class)
    @ResponseBody
    public RestResponse myException(HttpServletRequest request, HttpServletResponse response, MyException ex) {
        log.info(ex.getCode() + "->" + ex.getMsg());
        Map<String,Object> map = new HashMap<>();
        map.put("errMsg", ex.getMsg());
        map.put("res", response.getStatus());
        if(ex.getCode() == 404){
            map.put("url",request.getRequestURI());
            return RestResponse.failure("404错误").setData(map).setCode(404);
        }else{
            map.put("url", request.getRequestURI());
            return RestResponse.failure("500错误").setData(map).setCode(500);
        }
    }
}
